package sy6_Behavioral_Pattern.memento.ext;
import java.util.ArrayList;
import java.util.List;
/*
 * 实现多次Undo
 * 下中国象棋Chess，可能会悔棋
 */
class ChessMemento{  //角色：象棋棋子备忘录
	private String label;  //棋子名称
	private int x;  //横坐标
	private int y;  //纵坐标
	
	public ChessMemento(String label, int x, int y) {  //构造方法
		this.label=label;
		this.x=x;
		this.y=y;
	}
	public int getX() {
		return x;
	}
	public void setX(int x) {
		this.x = x;
	}
	public int getY() {
		return y;
	}
	public void setY(int y) {
		this.y = y;
	}
	public String getLabel() {
		return label;
	}
	public void setLabel(String label) {
		this.label = label;
	}
	
	@Override
	public String toString() {
		return "ChessMemento [label=" + label + ", x=" + x + ", y=" + y + "]";
	}
}

class ChessOriginator{  //角色：象棋棋子原发器Originator，用于创建和恢复备忘录
	private ChessMemento chessMemento;   //ChessOriginator聚合ChessMemento
	public ChessOriginator(ChessMemento chessMemento) {  //构造器
		this.chessMemento=chessMemento;
	}
	public void setX(int x) {
		chessMemento.setX(x);
	}
	public void setY(int y) {
		chessMemento.setY(y);
	}
	public ChessMemento createMemento() {  //保存当前状态至备忘录对象
		return new ChessMemento(chessMemento.getLabel(),chessMemento.getX(),chessMemento.getY());
	}
	public void restoreChessMemento(ChessMemento chessMemento) {  //通过备忘录对象恢复到历史的状态
		this.chessMemento.setLabel(chessMemento.getLabel());
		this.chessMemento.setX(chessMemento.getX());;
		this.chessMemento.setY(chessMemento.getY());
	}
	public void show() {  //显示原发器的当前状态
		System.out.println("棋子当前状态："+chessMemento.toString());
	}
}

class ChessCaretaker{  //角色：象棋棋子备忘录的看管者
	private List<ChessMemento>mementoList=new ArrayList<>();  //关联关系
	
	public void addMemento(ChessMemento chessMemento) {
		mementoList.add(chessMemento);  //添加备忘录
	}
	public ChessMemento getMemento(int i) {  //获取备忘录
		return mementoList.get(i);
	}
}

public class Client {  //客户端
	private static int index=0;  //统计步数
	private static ChessCaretaker chessCaretaker=new ChessCaretaker();
	public static void main(String[] args) {
		//初始化一个棋子对象（源发器）
		ChessOriginator originator = new ChessOriginator(new ChessMemento("车", 1, 1));  
		move(originator);  //走棋
		originator.setY(2); //目标位置
		move(originator);  //走棋
		
		originator.setX(6); //目标位置
		move(originator);  //走棋
		
		undo(originator);  //Undo
		undo(originator);  //Undo
		redo(originator);  //Redo
		redo(originator);  //Redo
	}
	private static void move(ChessOriginator chessOriginator) {  //走棋
		index++;
		chessCaretaker.addMemento(chessOriginator.createMemento());
		chessOriginator.show();
	}
	private static void undo(ChessOriginator chessOriginator) {
		System.out.print("悔棋（Undo），");
		index--;
		chessOriginator.restoreChessMemento(chessCaretaker.getMemento(index-1));
		chessOriginator.show();
	}
	private static void redo(ChessOriginator chessOriginator) {
		System.out.print("恢复（Redo），");
		index++;
		chessOriginator.restoreChessMemento(chessCaretaker.getMemento(index-1));
		chessOriginator.show();
	}
}
